﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace Edc.MMAssemblyManager
{
    public class AssemblyManager
    {
        public AssemblyVersion GetVersion(string filePath)
        {
            //[assembly: AssemblyVersion("1.0.4.0")]
            //[assembly: AssemblyFileVersion("1.0.4.0")]
            var versionRegex = new Regex(@"\[assembly\s*:\s*AssemblyVersion\s*\(\s*\""(?<major>\d+)\.(?<minor>\d+)\.(?<revision>\d+)\.(?<build>\d+)\""\s*\)\s*\]");

            using (var reader = new StreamReader(filePath))
            {
                string line = reader.ReadLine();
                while (line != null)
                {
                    // Scartiamo i commenti
                    if (!line.Trim().StartsWith("/"))
                    {

                        var match = versionRegex.Match(line);
                        if (match.Success)
                        {
                            var major = int.Parse(match.Groups["major"].Value);
                            var minor = int.Parse(match.Groups["minor"].Value);
                            var revision = int.Parse(match.Groups["revision"].Value);
                            var build = int.Parse(match.Groups["build"].Value);

                            return new AssemblyVersion(major, minor, revision, build);
                        }
                    }

                    line = reader.ReadLine();
                }
            }

            throw new Exception("No version found in file " + filePath);
        }

        public void UpdateVersion(string filePath, AssemblyVersion version)
        {
            //[assembly: AssemblyVersion("1.0.4.0")]
            //[assembly: AssemblyFileVersion("1.0.4.0")]
            var versionRegex = new System.Text.RegularExpressions.Regex(@"\[assembly\s*\:\s*AssemblyVersion\s*\(");
            var fileVersionRegex = new System.Text.RegularExpressions.Regex(@"\[assembly\s*\:\s*AssemblyFileVersion\s*\(");

            var bakFilePath = filePath + ".bak";
            File.Copy(filePath, bakFilePath, true);

            using(var reader = new StreamReader(bakFilePath , Encoding.UTF8))
            using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
            {
                string line = reader.ReadLine();
                while (line != null)
                {
                    // Scartiamo i commenti
                    if (line.Trim().StartsWith("/"))
                    {
                        writer.WriteLine(line);
                    }
                    else if (versionRegex.IsMatch(line))
                    {
                        writer.WriteLine(string.Format(@"[assembly: AssemblyVersion(""{0}"")]", version.ToString()));
                    }
                    else if (fileVersionRegex.IsMatch(line))
                    {
                        writer.WriteLine(string.Format(@"[assembly: AssemblyFileVersion(""{0}"")]", version.ToString()));
                    }
                    else
                    {
                        writer.WriteLine(line);
                    }
                
                    line = reader.ReadLine();
                }
            }
            File.Delete(bakFilePath);
        }

        public FileInfo FindProject(string sourceFilePath)
        {
            // Cerchiamo l'AssemblyInfo.
            // Iniziamo dalla direcotry dell'item corrente.
            var localDir = new DirectoryInfo(Path.GetDirectoryName(sourceFilePath));
            FileInfo localItemProject = null;
            while (localItemProject == null)
            {
                var pathFiles = localDir.GetFiles("*.csproj", SearchOption.TopDirectoryOnly);
                if (pathFiles.Length == 1)
                {
                    // Abbiamo trovato il csproj!
                    return pathFiles[0];
                }
                else if (pathFiles.Length > 1)
                {
                    throw new Exception("More than one csproj file found: " + pathFiles[0] + ", " + pathFiles[1] + ", ...");
                }
                else
                {
                    // Proviamo a salire di un livello.
                    localDir = localDir.Parent;
                    if (localDir == null)
                    {
                        // Siamo alla root. Fermati!
                        throw new Exception("No csproj file found!");
                    }
                }
            }

            throw new Exception("No csproj file found!");
        }
    }
}
